import string

class Instructions:
    def __init__(self, grs):
        self.grs = grs
        self.instrs = {
            'add16'   :  [3, ['w', 'w', 'w'], self.add16],
            'add32'   :  [3, ['v', 'v', 'v'], self.add32],
            'add64'   :  [3, ['u', 'u', 'u'], self.add64],
            'add16c'  :  [3, ['w', 'w', 'w'], self.add16c],
            'add32c'  :  [3, ['v', 'v', 'v'], self.add32c],
            'add64c'  :  [3, ['u', 'u', 'u'], self.add64c],
            'add16d'  :  [2, ['w', 'w'], self.add16d],
            'add32d'  :  [2, ['v', 'v'], self.add32d],
            'add64d'  :  [2, ['u', 'u'], self.add64d],
            'add16dc'  :  [2, ['w', 'w'], self.add16dc],
            'add32dc'  :  [2, ['v', 'v'], self.add32dc],
            'add64dc'  :  [2, ['u', 'u'], self.add64dc],
            'call'    :  [1, ['u'], self.call],
            'sub16'  :  [3, ['w', 'w', 'w'], self.sub16],
            'sub32'  :  [3, ['v', 'v', 'v'], self.sub32],
            'sub64'  :  [3, ['u', 'u', 'u'], self.sub64],
            'subb16'  :  [3, ['w', 'w', 'w'], self.subb16],
            'subb32'  :  [3, ['v', 'v', 'v'], self.subb32],
            'subb64'  :  [3, ['u', 'u', 'u'], self.subb64],
            'sub16d'  :  [2, ['w', 'w'], self.sub16d],
            'sub32d'  :  [2, ['v', 'v'], self.sub32d],
            'sub64d'  :  [2, ['u', 'u'], self.sub64d],
            'subb16d'  :  [2, ['w', 'w'], self.subb16d],
            'subb32d'  :  [2, ['v', 'v'], self.subb32d],
            'subb64d'  :  [2, ['u', 'u'], self.subb64d],
        }
    
    def add16(self, x):
        regs = []
        for i in range(3):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr16(regs[1]) + self.grs.read_gr16(regs[2])
        self.grs.write_gr16(tmp & 0xFFFF, regs[0])
   
    def add32(self, x):
        regs = []
        for i in range(3):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr32(regs[1]) + self.grs.read_gr32(regs[2])
        self.grs.write_gr32(tmp & 0xFFFFFFFF, regs[0])

    def add64(self, x):
        regs = []
        for i in range(3):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr64(regs[1]) + self.grs.read_gr64(regs[2])
        self.grs.write_gr64(tmp & 0xFFFFFFFFFFFFFFFF, regs[0])      

    def add16c(self, x):
        regs = []
        for i in range(3):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr16(regs[1]) + self.grs.read_gr16(regs[2])
        self.grs.write_gr16(tmp & 0xFFFF, regs[0])
   
    def add32c(self, x):
        regs = []
        for i in range(3):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr32(regs[1]) + self.grs.read_gr32(regs[2])
        self.grs.write_gr32(tmp & 0xFFFFFFFF, regs[0])

    def add64c(self, x):
        regs = []
        for i in range(3):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr64(regs[1]) + self.grs.read_gr64(regs[2])
        self.grs.write_gr64(tmp & 0xFFFFFFFFFFFFFFFF, regs[0])      
 
        
        
        
        
        
    def add16d(self, x):
        regs = []
        for i in range(2):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr16(regs[0]) + self.grs.read_gr16(regs[1])
        self.grs.write_gr16(tmp & 0xFFFF, regs[0])
        
    def add32d(self, x):
        regs = []
        for i in range(2):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr32(regs[0]) + self.grs.read_gr32(regs[1])
        self.grs.write_gr32(tmp & 0xFFFFFFFF, regs[0])
        
    def add64d(self, x):
        regs = []
        for i in range(2):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr64(regs[0]) + self.grs.read_gr64(regs[1])
        self.grs.write_gr64(tmp & 0xFFFFFFFFFFFFFFFF, regs[0])
              
    def add16dc(self, x):
        regs = []
        for i in range(2):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr16(regs[0]) + self.grs.read_gr16(regs[1])
        self.grs.write_gr16(tmp & 0xFFFF, regs[0])
        
    def add32dc(self, x):
        regs = []
        for i in range(2):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr32(regs[0]) + self.grs.read_gr32(regs[1])
        self.grs.write_gr32(tmp & 0xFFFFFFFF, regs[0])
        
    def add64dc(self, x):
        regs = []
        for i in range(2):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr64(regs[0]) + self.grs.read_gr64(regs[1])
        self.grs.write_gr64(tmp & 0xFFFFFFFFFFFFFFFF, regs[0])

        
        

        
        
    def sub16(self, x):
        regs = []
        for i in range(3):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr16(regs[1]) - self.grs.read_gr16(regs[2])
        self.grs.write_gr16(tmp & 0xFFFF, regs[0])   
        
    def sub32(self, x):
        regs = []
        for i in range(3):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr32(regs[1]) - self.grs.read_gr32(regs[2])
        self.grs.write_gr32(tmp & 0xFFFFFFFF, regs[0])        
        
    def sub64(self, x):
        regs = []
        for i in range(3):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr64(regs[1]) - self.grs.read_gr64(regs[2])
        self.grs.write_gr64(tmp & 0xFFFFFFFFFFFFFFFF, regs[0])

    def subb16(self, x):
        regs = []
        for i in range(3):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr16(regs[1]) - self.grs.read_gr16(regs[2])
        self.grs.write_gr16(tmp & 0xFFFF, regs[0])   
        
    def subb32(self, x):
        regs = []
        for i in range(3):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr32(regs[1]) - self.grs.read_gr32(regs[2])
        self.grs.write_gr32(tmp & 0xFFFFFFFF, regs[0])        
        
    def subb64(self, x):
        regs = []
        for i in range(3):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr64(regs[1]) - self.grs.read_gr64(regs[2])
        self.grs.write_gr64(tmp & 0xFFFFFFFFFFFFFFFF, regs[0])
 
        
        
        
        
        

    def sub16d(self, x):
        regs = []
        for i in range(2):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr16(regs[0]) - self.grs.read_gr16(regs[1])
        self.grs.write_gr16(tmp & 0xFFFF, regs[0])   
        
    def sub32d(self, x):
        regs = []
        for i in range(2):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr32(regs[0]) - self.grs.read_gr32(regs[1])
        self.grs.write_gr32(tmp & 0xFFFFFFFF, regs[0])        
        
    def sub64d(self, x):
        regs = []
        for i in range(2):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr64(regs[0]) - self.grs.read_gr64(regs[1])
        self.grs.write_gr64(tmp & 0xFFFFFFFFFFFFFFFF, regs[0])    
        
    def subb16d(self, x):
        regs = []
        for i in range(2):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr16(regs[0]) - self.grs.read_gr16(regs[1])
        self.grs.write_gr16(tmp & 0xFFFF, regs[0])   
        
    def subb32d(self, x):
        regs = []
        for i in range(2):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr32(regs[0]) - self.grs.read_gr32(regs[1])
        self.grs.write_gr32(tmp & 0xFFFFFFFF, regs[0])        
        
    def subb64d(self, x):
        regs = []
        for i in range(2):
            regs += [self.get_regs_num(x[i])]
        tmp = self.grs.read_gr64(regs[0]) - self.grs.read_gr64(regs[1])
        self.grs.write_gr64(tmp & 0xFFFFFFFFFFFFFFFF, regs[0])        
    
    
    
    
    def call(self, x):
        return
    
    
    def get_regs_num(self, argv):
        if argv != '':
            if argv[0] in ['w', 'u', 'v']:
                return string.atoi(argv[1:])
        return argv